package ar.edu.unicen.exa.isistan.archassis.model.persistence;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.List;

import ar.edu.unicen.exa.isistan.archassis.DiffRequestData;
import ar.edu.unicen.exa.isistan.archassis.ia.api.db.JavaClass;
import ar.edu.unicen.exa.isistan.archassis.rcs.IRevisionControlSystem;
import ar.edu.unicen.exa.isistan.archassis.rcs.IVersion;
import ar.edu.unicen.exa.isistan.archassis.rcs.svn.SVNRevisionControlSystem;
import ar.edu.unicen.exa.isistan.archassis.source.FileSourceStrategy;
import ar.edu.unicen.exa.isistan.archassis.source.ISourceStrategy;
import ar.edu.unicen.exa.isistan.archassis.source.RCSSourceStrategy;

public class PersistenceManager {
	
	public static List<JavaClass> getCacheDiff(ISourceStrategy sourceStrategy) {
		if (sourceStrategy instanceof RCSSourceStrategy) {
			RCSSourceStrategy rcsss = (RCSSourceStrategy) sourceStrategy;
			return getCacheDiff(rcsss.getRcs(), rcsss.getVersionFrom(), rcsss.getVersionTo());
		} else if (sourceStrategy instanceof FileSourceStrategy) {
			//no se persiste!
		} else {
			System.err.println("No hay manera de persistir el ISourceStrategy dado");
		}
		return null;
	}
	public static List<JavaClass> getCacheDiff(IRevisionControlSystem rcs, IVersion versionFrom, IVersion versionTo) {
		//RCSSourceStrategy implements ISourceStrategy
		File cacheFile = getCacheFile(rcs, versionFrom, versionTo);
		
		List<JavaClass> result = (List<JavaClass>)loadSerializable(cacheFile);
		
		return result;
	}
	
	public static void setCacheDiff(ISourceStrategy sourceStrategy, List<JavaClass> result) {
		if (sourceStrategy instanceof RCSSourceStrategy) {
			RCSSourceStrategy rcsss = (RCSSourceStrategy) sourceStrategy;
			setCacheDiff(rcsss.getRcs(), rcsss.getVersionFrom(), rcsss.getVersionTo(), result);
		} else if (sourceStrategy instanceof FileSourceStrategy) {
			//no se persiste!
		} else {
			System.err.println("No hay manera de persistir el ISourceStrategy dado");
		}

	}
	public static void setCacheDiff(IRevisionControlSystem rcs, IVersion versionFrom, IVersion versionTo, List<JavaClass> result) {
		File cacheFile = getCacheFile(rcs, versionFrom, versionTo);
		storeSerializable(cacheFile, result);
		
	}
	
	private static File getCacheFile(IRevisionControlSystem rcs, IVersion versionFrom, IVersion versionTo) {
		
		DiffRequestData tempFile = rcs.getDiffRequestData();
		return new File(tempFile.getRootTempPath(), "cache_" + versionFrom.getID() + "-" + versionTo.getID() + ".bin");

	}
	
	private static void storeSerializable(File aFile, Object o) {
		try {
			ObjectOutputStream fileOut = new ObjectOutputStream(new FileOutputStream(aFile));
			fileOut.writeObject(o);
			fileOut.close();
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}
	
	private static Object loadSerializable(File aFile) {
		if (!aFile.isFile()) {
			return null;
		}
		Object result = null;
		try {

			ObjectInputStream fileIn = new ObjectInputStream(new FileInputStream(aFile));
			result = fileIn.readObject();
			fileIn.close();
		} catch (Exception e) {
			// TODO: handle exception
			System.err.println(e.getMessage());
		}
		return result;
	}

	public static List<IVersion> getCacheVersions(SVNRevisionControlSystem rcs) {
		DiffRequestData tempFile = rcs.getDiffRequestData();
		File cacheVersionFile = new File(tempFile.getRootTempPath(), "cache_versions.bin");
		List<IVersion> result = (List<IVersion>)loadSerializable(cacheVersionFile);
		
//		if (result == null) {
//			result = rcs.getWorkingVersions();
//			storeSerializable(cacheVersionFile, result);
//		}
		return result;
		
	}
	public static void setCacheVersions(SVNRevisionControlSystem rcs, List<IVersion> versions) {
		DiffRequestData tempFile = rcs.getDiffRequestData();
		File cacheVersionFile = new File(tempFile.getRootTempPath(), "cache_versions.bin");
		storeSerializable(cacheVersionFile, versions);
	}

	
}
